/*
 * Copyright (c) 2007, Nathan Sturtevant
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of Alberta nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.pathmachine.mm;

import java.util.ArrayList;
import java.util.List;

/**
 * MinimalSearchEnvironment
 *
 * This is an implementation of a search environment for performing searches
 * on the map abstraction. 32-bit nodes are mapped to the abstraction using
 * 16 bits for each of the sector and region
 * 
 * @author Nathan Sturtevant
 * @author <a href="mailto:eriq.adams@gmail.com">Eriq Muhammad Adams J.</a>
 */
public class MinimalSearchEnvironment extends SearchEnvironment {

    private MinimalSectorAbstraction msa;

    public MinimalSearchEnvironment(MinimalSectorAbstraction msa) {
        this.msa = msa;
    }

    @Override
    public double HCost(int node1, int node2) {
        Point2D p = msa.getXYLocation(node1 >> 16, node1 & 0xFFFF);
        Point2D p2 = msa.getXYLocation(node2 >> 16, node2 & 0xFFFF);
        int x1 = p.x, x2 = p2.x, y1 = p.y, y2 = p2.y;
        double a = ((x1 > x2) ? (x1 - x2) : (x2 - x1));
        double b = ((y1 > y2) ? (y1 - y2) : (y2 - y1));
        double val = (a > b) ? (b * Map.ROOT_TWO + a - b) : (a * Map.ROOT_TWO + b - a);
        return val;
    }

    @Override
    public List<Integer> getNeighbors(int nodeID) {
        List<Integer> neighbors = new ArrayList<Integer>();
        List<TempEdgeData> edges = new ArrayList<TempEdgeData>();
        // sector ... abstraction
        msa.getNeighbors(nodeID >> 16, nodeID & 0xFFFF, edges);
        for (int x = 0; x < edges.size(); x++) {
            int sector = msa.getAdjacentSector(nodeID >> 16, edges.get(x).direction);
            int region = edges.get(x).to;
            neighbors.add((sector << 16) | region);
        }
        return neighbors;
    }
}
